/*
    Copyright (C) 2011  Lucas Paradisi, FuDePAN


    This file is part of the FuDePAN's Discrete Molecular Dynamics Engine.


    FDMDE is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.


    FDMDE is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.


    You should have received a copy of the GNU General Public License
    along with MiLi.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <list>
#include <string>
#include <mili/mili.h>

class Mech2Dyn
{

    typedef float Point;
    typedef std::string Id;
    typedef int Color;
    typedef std::list<Color> Colors;
    typedef int Mass;
    typedef float Diameter;
    typedef size_t Quantity;
    typedef float Parameter;
    struct ClassPair
    {
        Id class1;
        Id class2;
    };
    typedef std::list<ClassPair> ClassPairs;
    typedef std::list<Parameter> Parameters;
    typedef std::list<Id> Classes;

    struct Particle
    {

        Id id;
        Id fqn;
        Point x;
        Point y;
        Point z;


        Particle(const Id& id, const Id& fqn)
            : id(id),
              fqn(fqn)
        {
        }

        void setPosition(Point newx, Point newy, Point newz)
        {
            x = newx;
            y = newy;
            z = newz;
        }

    };

    struct Class
    {

        Id id;
        Mass mass;
        Diameter diameter;
        Colors colors;

        Class(const Id& id, Mass mass, Diameter diameter)
            : id(id),
              mass(mass),
              diameter(diameter)
        {
        }

    };

    struct Function
    {

        Id id;
        Quantity numOfParameters;
        std::string tags;

    };

    struct Interaction
    {

        Id id;
        Id function;

        ClassPairs pairs;
        Parameters parameters;
        Classes classes;


        Interaction(const Id& newId, const Id& newFunction)
            : id(newId),
              function(newFunction)
        {
        }

        void addPair(const std::string& p1, const std::string& p2)
        {
            ClassPair pair = {p1, p2};
            insert_into(pairs, pair);
        }

    };

    struct System
    {

        std::list<Particle> particles;
        std::list<Class> classes;
        std::list<Interaction> interactions;
        std::list<Function> functions;

        void addFunction(const Id& newId, Quantity newParameters, const std::string& newTags)
        {
            Function aux = {newId, newParameters, newTags};
            insert_into(functions, aux);
        }

    };

    
    std::string in_fname;
    std::string out_fname;
    System data;

public:

    Mech2Dyn()
    {
    }

    Mech2Dyn(const std::string& inFilename, const std::string& outFilename = "Dynamo.xml")
        : in_fname(inFilename),
          out_fname(outFilename)
    {
    }

    void set_inFilename(const std::string& name)
    {
        in_fname = name;
    }

    void set_outFilename(const std::string& name)
    {
        out_fname = name;
    }

    int convert();

};
